package android.slc.mp.ui.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.slc.ml.MediaLoader;
import android.slc.ml.bean.i.IPropertyFile;
import android.slc.mp.R;
import android.slc.mp.SlcMp;
import android.slc.mp.po.SelectEvent;
import android.slc.mp.po.i.IBaseItem;
import android.slc.mp.ui.SlcIMpDelegate;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.collection.ArrayMap;
import androidx.collection.SparseArrayCompat;
import androidx.fragment.app.Fragment;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by slc
 */
public class SlcMpDelegateImp implements SlcIMpDelegate {
    private Bundle mBundle;//文件选择界面参数
    private final SparseArrayCompat<String> mTableTitle = new SparseArrayCompat<>();//多种文件的选择是显示的table的title集合
    private Map<Integer, IPropertyFile> mediaTypeFilePropertyList;//文件过滤器
    private Map<Integer, Integer> mediaTypeMaxPickerList;//媒体类型最大可选数
    private final ArrayMap<Long, IBaseItem> selectItemArrayMap = new ArrayMap<>();//选择过的文件集合
    private final List<WeakReference<OnSelectEventListener>> onSelectEventListenerWeakReferenceList = new ArrayList<>();//选择事件集合
    private Fragment mFragment;//fragment
    private Activity mActivity;//activity

    public SlcMpDelegateImp(Activity activity) {
        this.mActivity = activity;
        mBundle = activity.getIntent().getExtras();
        initData();
    }

    public SlcMpDelegateImp(Fragment fragment) {
        this.mFragment = fragment;
        mBundle = fragment.getArguments();
        initData();
    }

    private void initData() {
        //如果文件选择参数为空，则初始化一个默认的参数
        if (mBundle == null) {
            mBundle = new Bundle();
        }
        //初始化文件选择类型，如果文件选择类型为空，则使用默认配置的文件选择类型
        ArrayList<Integer> mediaTypeList = mBundle.getIntegerArrayList(SlcMp.Key.KEY_MEDIA_TYPE_LIST);
        if (mediaTypeList == null) {
            mediaTypeList = new ArrayList<>();
        }
        if (mediaTypeList.isEmpty()) {
            mediaTypeList.add(SlcMp.MEDIA_TYPE_PHOTO);
            mediaTypeList.add(SlcMp.MEDIA_TYPE_VIDEO);
            mediaTypeList.add(SlcMp.MEDIA_TYPE_AUDIO);
            mediaTypeList.add(SlcMp.MEDIA_TYPE_FILE);
            mBundle.putIntegerArrayList(SlcMp.Key.KEY_MEDIA_TYPE_LIST, mediaTypeList);
        }
        //媒体类型最大可选数
        mediaTypeMaxPickerList = (HashMap<Integer, Integer>) mBundle.getSerializable(SlcMp.Key.KEY_MEDIA_TYPE_MAX_PICKER_LIST);
        if (mediaTypeMaxPickerList == null) {
            mediaTypeMaxPickerList = new HashMap<>();
        }
        //初始化文件混合选择集合
        ArrayList<Integer> mediaTypeMuddyList = mBundle.getIntegerArrayList(SlcMp.Key.KEY_MEDIA_TYPE_MUDDY_LIST);
        if (mediaTypeMuddyList == null) {
            mediaTypeMuddyList = new ArrayList<>();
        }
        if (mediaTypeMuddyList.isEmpty()) {
            mediaTypeMuddyList.addAll(mediaTypeList);
            mBundle.putIntegerArrayList(SlcMp.Key.KEY_MEDIA_TYPE_MUDDY_LIST, mediaTypeMuddyList);
        }
        //设置文件过滤器集合
        mediaTypeFilePropertyList = (HashMap<Integer, IPropertyFile>) mBundle.getSerializable(SlcMp.Key.KEY_MEDIA_TYPE_FILE_PROPERTY_LIST);
        if (mediaTypeFilePropertyList == null) {
            mediaTypeFilePropertyList = new HashMap<>();
        }
        //初始化每个页面的一行的个数，仅在网络的列表有效
        if (getSpanCount() < 1) {
            mBundle.putInt(SlcMp.Key.KEY_SPAN_COUNT, SlcMp.Value.VALUE_SPAN_COUNT_DEF_VALUE);
        }
        //初始化最多可以选择多少个
        if (getMaxCount() < 1) {
            mBundle.putInt(SlcMp.Key.KEY_MAX_PICKER, SlcMp.Value.VALUE_DEF_MAX_PICKER);
        }
        //设置文件选择页面table的title集合
        HashMap<Integer, String> mediaTypeTitleList = (HashMap<Integer, String>) mBundle.getSerializable(SlcMp.Key.KEY_MEDIA_TYPE_TITLE_LIST);
        if (mediaTypeTitleList == null) {
            mediaTypeTitleList = new HashMap<>();
        }
        //初始化title
        for (Integer type : mediaTypeList) {
            String title = mediaTypeTitleList.get(type);
            switch (type) {
                case SlcMp.MEDIA_TYPE_PHOTO:
                    mTableTitle.put(SlcMp.MEDIA_TYPE_PHOTO, TextUtils.isEmpty(title) ? SlcMp.getInstance().getApp().getString(R.string.slc_m_p_photo) : title);
                    break;
                case SlcMp.MEDIA_TYPE_VIDEO:
                    mTableTitle.put(SlcMp.MEDIA_TYPE_VIDEO, TextUtils.isEmpty(title) ? SlcMp.getInstance().getApp().getString(R.string.slc_m_p_video) : title);
                    break;
                case SlcMp.MEDIA_TYPE_AUDIO:
                    mTableTitle.put(SlcMp.MEDIA_TYPE_AUDIO, TextUtils.isEmpty(title) ? SlcMp.getInstance().getApp().getString(R.string.slc_m_p_audio) : title);
                    break;
                case SlcMp.MEDIA_TYPE_FILE:
                    mTableTitle.put(SlcMp.MEDIA_TYPE_FILE, TextUtils.isEmpty(title) ? SlcMp.getInstance().getApp().getString(R.string.slc_m_p_file) : title);

                    break;
                default:
                    //mTableTitle.put(type, title);
                    mTableTitle.put(type, TextUtils.isEmpty(title) ? SlcMp.getInstance().getApp().getString(R.string.slc_m_p_file) : title);
                    break;
            }
        }
    }

    @Override
    public Bundle getParameter() {
        return mBundle;
    }

    @Override
    public Context getContext() {
        return mActivity;
    }

    @Override
    public int getSpanCount() {
        return mBundle.getInt(SlcMp.Key.KEY_SPAN_COUNT);
    }

    @Override
    public int getSelectItemCount() {
        return selectItemArrayMap.size();
    }

    /**
     * 根据媒体类型获取选择的个数
     *
     * @param mediaType
     * @return
     */
    @Override
    public int getSelectItemCountByMediaType(int mediaType) {
        int count = 0;
        Collection<IBaseItem> values = selectItemArrayMap.values();
        for (IBaseItem item : values) {
            if (item.getMediaTypeTag() == mediaType) {
                count++;
            }
        }
        return count;
    }

    @Override
    public int getMaxCount() {
        return mBundle.getInt(SlcMp.Key.KEY_MAX_PICKER);
    }

    @Override
    public Integer getMaxCountByMediaType(int mediaType, boolean isNullApplyGlobalMax) {
        Integer maxCount = mediaTypeMaxPickerList.get(mediaType);
        if (maxCount != null) {
            return maxCount;
        }
        return isNullApplyGlobalMax ? getMaxCount() : null;
    }

    @Override
    public boolean isMultipleSelection() {
        return mBundle.getBoolean(SlcMp.Key.KEY_IS_MULTIPLE_SELECTION, SlcMp.Value.VALUE_DEF_MULTIPLE_SELECTION);
    }

    @Override
    public boolean isMultipleMediaType() {
        return mBundle.getBoolean(SlcMp.Key.KEY_IS_MULTIPLE_MEDIA_TYPE, SlcMp.Value.VALUE_DEF_MULTIPLE_MEDIA_TYPE);
    }

    @Override
    public String getTitleByMediaType(int mediaType) {
        return mTableTitle.get(mediaType);
    }

    @Override
    public String getTitleByPosition(int position) {
        return getTitleByMediaType(getMediaTypeList().get(position));
    }

    @Override
    public List<Integer> getMediaTypeList() {
        return mBundle.getIntegerArrayList(SlcMp.Key.KEY_MEDIA_TYPE_LIST);
    }

    @Override
    public List<Integer> getMediaTypeMuddyList() {
        return mBundle.getIntegerArrayList(SlcMp.Key.KEY_MEDIA_TYPE_MUDDY_LIST);
    }

    @Override
    public Map<Integer, IPropertyFile> getMediaTypeFilePropertyList() {
        return mediaTypeFilePropertyList;
    }

    @Override
    public IPropertyFile getFilePropertyWithMediaType(int mediaType) {
        return mediaTypeFilePropertyList.get(mediaType);
    }

    @Override
    public ArrayMap<Long, IBaseItem> getSelectItemArrayMap() {
        return selectItemArrayMap;
    }

    @Override
    public boolean addItem(IBaseItem baseItem) {
        boolean isSelect = false;
        if (baseItem != null) {
            //是否支持选择多个
            if (isMultipleSelection()) {
                //是否支持混合媒体类型多选且选择该媒体类型前是否选择过其他的媒体类型
                if (!isMultipleMediaType() && existMultipleMediaType(baseItem)) {
                    noAllowMultipleMediaType(baseItem);
                    return false;
                }
                //混合选择是否支持该文件的媒体类型
                if (!getMediaTypeMuddyList().contains(baseItem.getMediaTypeTag())) {
                    notAllowedMuddyMediaType(baseItem);
                    return false;
                }
                //是否超过最大选择数
                int selectItemArrayMapSize = selectItemArrayMap.size();
                if (selectItemArrayMapSize < getMaxCount()) {
                    //判断当前媒体类型是否超出
                    if (getSelectItemCountByMediaType(baseItem.getMediaTypeTag()) < getMaxCountByMediaType(baseItem.getMediaTypeTag())) {
                        isSelect = true;
                        baseItem.setChecked(true);
                        selectItemArrayMap.put(baseItem.getId(), baseItem);
                        onCheck(baseItem);
                        onSelectChange(baseItem);
                    } else {
                        //如果超过该媒体类型所允许的最大值
                        onOverflow(baseItem, true);
                    }
                } else {
                    //如果超过，则发送超过最大个数通知
                    onOverflow(baseItem, false);
                }
            } else {
                isSelect = true;
                baseItem.setChecked(true);
                onCheck(baseItem);
                removeAll();
                selectItemArrayMap.put(baseItem.getId(), baseItem);
                onSelectChange(baseItem);
            }
        }
        return isSelect;
    }

    /**
     * 多选模式下，首先选择的是否是该媒体类型
     *
     * @param baseItem
     * @return
     */
    protected boolean existMultipleMediaType(IBaseItem baseItem) {
        if (selectItemArrayMap.isEmpty()) {
            return false;
        }
        return selectItemArrayMap.valueAt(0).getMediaTypeTag() != baseItem.getMediaTypeTag();
    }

    @Override
    public boolean removeItem(IBaseItem baseItem) {
        if (baseItem != null) {
            baseItem.setChecked(false);
            onCheck(baseItem);
            selectItemArrayMap.remove(baseItem.getId());
            onSelectChange(baseItem);
        }
        return true;
    }

    /**
     * 添加所有(文件选择)
     * 全选逻辑未完成，需要判断多种类型混合逻辑和个数限制逻辑
     *
     * @param baseItemList
     * @Deprecated 正常情况下不会有这种，除非没有选择个数限制
     */
    @Override
    public void addAll(List<IBaseItem> baseItemList) {
        //此处先注释，需要完善逻辑
        /*if (baseItemList != null) {
            for (IBaseItem baseItem : baseItemList) {
                baseItem.setChecked(true);
                selectItemArrayMap.put(baseItem.getId(), baseItem);
                onCheck(baseItem);
            }
        }
        onSelectChange();*/
    }

    @Override
    public void removeAll() {
        for (Map.Entry<Long, IBaseItem> itemEntry : selectItemArrayMap.entrySet()) {
            itemEntry.getValue().setChecked(false);
            onCheck(itemEntry.getValue());
        }
        selectItemArrayMap.clear();
        onRemoveAll();
    }

    @Override
    public void addOnSelectEventListener(@NonNull OnSelectEventListener onSelectEventListener) {
        onSelectEventListenerWeakReferenceList.add(new WeakReference<>(onSelectEventListener));
    }

    /**
     * 通知移除所有
     */
    protected void onRemoveAll() {
        for (WeakReference<OnSelectEventListener> onSelectChangeListenerWeakReference : onSelectEventListenerWeakReferenceList) {
            OnSelectEventListener onSelectEventListener = onSelectChangeListenerWeakReference.get();
            if (onSelectEventListener != null) {
                onSelectEventListener.onSelectEvent(SelectEvent.EVENT_REMOVE_ALL, new SelectEvent());
            }
        }
    }

    /**
     * 通知选择改变
     * 调用此方法时，表示已经判断过超过限制、允许多选等逻辑
     */
    protected void onSelectChange(IBaseItem baseItem) {
        for (WeakReference<OnSelectEventListener> onSelectChangeListenerWeakReference : onSelectEventListenerWeakReferenceList) {
            OnSelectEventListener onSelectEventListener = onSelectChangeListenerWeakReference.get();
            if (onSelectEventListener != null) {
                int listenerMediaType = (int) onSelectEventListener.getListenerMediaType();
                if (listenerMediaType == baseItem.getMediaTypeTag() || listenerMediaType == SlcMp.MEDIA_TYPE_NULL) {
                    onSelectEventListener.onSelectEvent(SelectEvent.EVENT_SELECT_COUNT, new SelectEvent()
                            .putOfChained(SelectEvent.PARAMETER_SELECT_ITEM_COUNT, getSelectItemCount())
                            .putOfChained(SelectEvent.PARAMETER_MEDIA_TYPE_MAX_COUNT, getMaxCountByMediaType(baseItem.getMediaTypeTag()))
                            .putOfChained(SelectEvent.PARAMETER_MEDIA_TYPE_SELECT_ITEM_COUNT, getSelectItemCountByMediaType(baseItem.getMediaTypeTag()))
                            .putOfChained(SelectEvent.PARAMETER_IS_MULTIPLE_MEDIA_TYPE, isMultipleMediaType())//按照目前的逻辑来看，此处不需要考虑getMediaTypeMuddyList的逻辑，因为不支持时不会调用onSelectChange()方法
                            .putOfChained(SelectEvent.PARAMETER_IS_MULTIPLE_SELECTION, isMultipleSelection()));
                }
            }
        }
    }

    /**
     * 通知选择或取消了一个
     *
     * @param baseItem
     */
    protected void onCheck(IBaseItem baseItem) {
        for (WeakReference<OnSelectEventListener> onSelectChangeListenerWeakReference : onSelectEventListenerWeakReferenceList) {
            OnSelectEventListener onSelectEventListener = onSelectChangeListenerWeakReference.get();
            if (onSelectEventListener != null) {
                int listenerMediaType = (int) onSelectEventListener.getListenerMediaType();
                if (listenerMediaType == baseItem.getMediaTypeTag() || listenerMediaType == SlcMp.MEDIA_TYPE_NULL) {
                    onSelectEventListener.onSelectEvent(SelectEvent.EVENT_CHECK, new SelectEvent()
                            .putOfChained(SelectEvent.PARAMETER_ITEM, baseItem));
                }
            }
        }
    }

    /**
     * 选择溢出
     *
     * @param isMediaTypeOverflow 是否时媒体类型溢出
     */
    protected void onOverflow(IBaseItem baseItem, boolean isMediaTypeOverflow) {
        for (WeakReference<OnSelectEventListener> onSelectChangeListenerWeakReference : onSelectEventListenerWeakReferenceList) {
            OnSelectEventListener onSelectEventListener = onSelectChangeListenerWeakReference.get();
            if (onSelectEventListener != null) {
                int listenerMediaType = (int) onSelectEventListener.getListenerMediaType();
                if (listenerMediaType == baseItem.getMediaTypeTag() || listenerMediaType == SlcMp.MEDIA_TYPE_NULL) {
                    SelectEvent selectEvent = new SelectEvent();
                    if (isMediaTypeOverflow) {
                        selectEvent.putOfChained(SelectEvent.PARAMETER_MEDIA_TYPE_MAX_COUNT, getMaxCountByMediaType(baseItem.getMediaTypeTag()));
                    }
                    onSelectEventListener.onSelectEvent(SelectEvent.EVENT_OVER_FLOW, selectEvent);
                }
            }
        }
    }

    /**
     * 选择了不允许的类型
     */
    protected void notAllowedMuddyMediaType(IBaseItem baseItem) {
        for (WeakReference<OnSelectEventListener> onSelectChangeListenerWeakReference : onSelectEventListenerWeakReferenceList) {
            OnSelectEventListener onSelectEventListener = onSelectChangeListenerWeakReference.get();
            if (onSelectEventListener != null) {
                int listenerMediaType = (int) onSelectEventListener.getListenerMediaType();
                if (listenerMediaType == baseItem.getMediaTypeTag() || listenerMediaType == SlcMp.MEDIA_TYPE_NULL) {
                    onSelectEventListener.onSelectEvent(SelectEvent.EVENT_NO_ALLOW_MUDDY_MEDIA_TYPE, new SelectEvent()
                            .putOfChained(SelectEvent.PARAMETER_ITEM, baseItem));
                }
            }
        }
    }

    /**
     * 不允许选择多种类型
     *
     * @param baseItem
     */
    protected void noAllowMultipleMediaType(IBaseItem baseItem) {
        for (WeakReference<OnSelectEventListener> onSelectChangeListenerWeakReference : onSelectEventListenerWeakReferenceList) {
            OnSelectEventListener onSelectEventListener = onSelectChangeListenerWeakReference.get();
            if (onSelectEventListener != null) {
                int listenerMediaType = (int) onSelectEventListener.getListenerMediaType();
                if (listenerMediaType == baseItem.getMediaTypeTag() || listenerMediaType == SlcMp.MEDIA_TYPE_NULL) {
                    onSelectEventListener.onSelectEvent(SelectEvent.EVENT_NO_ALLOW_MULTIPLE_MEDIA_TYPE, new SelectEvent()
                            .putOfChained(SelectEvent.PARAMETER_ITEM, baseItem));
                }
            }
        }
    }


    @Override
    public void complete() {
        if (this.mFragment != null) {
            //TODO 使用fragment完成
        } else {
            ArrayList<IBaseItem> selectItems = new ArrayList<>(selectItemArrayMap.values());
            //SlcMpResultModel.getInstance().setValue(selectItems);
            Intent intent = new Intent();
            intent.putExtra(SlcMp.Key.KEY_RESULT_LIST, selectItems);
            this.mActivity.setResult(Activity.RESULT_OK, intent);
            this.mActivity.finish();
        }
    }

    @Override
    public void destroy() {
        //移除临时的选择配置 防止没存泄露
        SlcMp.getInstance().removeTemporaryMpConfig();
        //媒体加载器注销，防止内存泄漏
        MediaLoader.getLoader().release();
    }
}
